﻿using NCS.IConnect.Core.Utilities;
using NCS.IConnect.Core.WebApi.Properties;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace NCS.IConnect.Core.WebApi.Validation
{
    /// <summary>
    /// Validate a string name and ensure it is one option of specified enum.
    /// </summary>
    [AttributeUsage( AttributeTargets.Property| AttributeTargets.Parameter|  AttributeTargets.Field)]
    [ComVisible(false)]
    public class EnumNameAttribute : ValidationAttribute
    {
        /// <summary>
        /// Gets the type of the enum.
        /// </summary>
        /// <value>The type of the enum.</value>
        public Type EnumType { get; private set; }

        /// <summary>
        /// Gets a value indicating whether [ignore case].
        /// </summary>
        /// <value><c>true</c> if [ignore case]; otherwise, <c>false</c>.</value>
        public bool IgnoreCase { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="EnumNameAttribute"/> class.
        /// </summary>
        /// <param name="enumType">Type of the enum.</param>
        /// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
        /// <exception cref="ArgumentException">enumType</exception>
        public EnumNameAttribute(Type enumType, bool ignoreCase = false)
        {
            Guard.ArgumentNotNull(enumType, "enumType");
            if (!enumType.IsEnum)
            {
                throw new ArgumentException(Resources.ExceptionInvalidEnumType.Format(new string[] { enumType.FullName }), "enumType");
            }
            this.EnumType = enumType;
            this.IgnoreCase = ignoreCase;
        }

        /// <summary>
        /// Determines whether the specified value of the object is valid.
        /// </summary>
        /// <param name="value">The value of the object to validate.</param>
        /// <returns>true if the specified value is valid; otherwise, false.</returns>
        public override bool IsValid(object value)
        {
            string value1 = value as string;
            if (value1 == null)
            {
                return true;
            }
            return this.EnumType.GetEnumNames().Any(name => string.Compare(value1, name, this.IgnoreCase) == 0);
        }
    }
}
